#ifndef COMMON_H
#define COMMON_H

#include <math.h>

#define CELL_KEYRELEASE -1
#define CELL_SHIFT 0
#define CELL_ALT 1
#define CELL_DELETE 2

#define CELL_STOP -1
#define CELL_CAMERAMOVE 0
#define CELL_CAMERAROTATE 1
#define CELL_CAMERAZOOM 2
#define CELL_SELECT 3
#define CELL_TRANSLATE 4
#define CELL_ROTATE 5
#define CELL_SCALE 6
#define CELL_EDITMESHPOINT 7
#define CELL_EDITMESHFACE 8

#define CELL_PERSPECTIVE 0
#define CELL_FOURVIEW 1
#define CELL_TOP 2
#define CELL_RIGHT 3
#define CELL_FRONT 4
#define CELL_PALNEBACED 5

#define CELL_TRIANGLE 0
#define CELL_LINE 1
#define CELL_POINT 2

#define LOW_TRANSPARENCY 1000
#define MID_TRANSPARENCY 1001
#define HIGH_TRANSPARENCY 1002

#define BLUE 2000
#define GREEN 2001
#define RED 2002
#define PURPLE 2003

#define CELL_TRANSLATEAXISX 10000
#define CELL_TRANSLATEAXISY 10001
#define CELL_TRANSLATEAXISZ 10002
#define CELL_TRANSLATEAXISXY 10003
#define CELL_TRANSLATEAXISYZ 10004
#define CELL_TRANSLATEAXISZX 10005
#define CELL_TRANSLATEBASEPLANE 10006
#define CELL_TRANSLATEPLANE 10007
#define CELL_TRANSLATEPOINT 10008
#define CELL_TRANSLATEDEPTH 10008
#define CELL_ROTATEAXISX 10010
#define CELL_ROTATEAXISY 10011
#define CELL_ROTATEAXISZ 10012
#define CELL_SCALEAXISX 10013
#define CELL_SCALEAXISY 10014
#define CELL_SCALEAXISZ 10015
#define CELL_SCALEAXISXYZ 10016
#define CELL_CTRLPOINT1 10017
#define CELL_CTRLPOINT2 10018

#define CELL_NOPAINT -1
#define CELL_LIQUIDFY 0

#define CELL_FOURVIEWMARGIN 5

#define BUFSIZE 512

#define CELL_EPS 10e-8
#define CELL_MAX 100000000.0

#define CELL_NONE -1
#define CELL_MESH 0
#define CELL_SPHERE 1
#define CELL_CYLINDER 2
#define CELL_CUBE 3
#define CELL_PLANE 4
#define CELL_OPENCYLINDER 5
#define CELL_LINE 6

#define CELL_OPENGLOFFSETX 62
#define CELL_OPENGLOFFSETY 97

//!  A Vector3 class.
/*!
  It is class of vector in 3D coordinate.
*/

class Vector3
{
public:
    //! A constructor.
    Vector3() {x = y = z = 0.0f;}

    //! A constructor.
    /*!
          \param a x coordinate value.
          \param b y coordinate value.
          \param c z coordinate value.
          \return return a Vector3.
    */
    Vector3(double a, double b, double c) : x(a), y(b), z(c){ }

    //! Set values.
    /*!
          \param a x coordinate value.
          \param b y coordinate value.
          \param c z coordinate value.
    */
    void Set(double a, double b, double c) {x = a; y = b; z = c;}

    //! Get the lenght of a vector.
    /*!
          \return return the lenght of the Vector3.
    */
    double Lenght() {return sqrt(x*x + y*y + z*z);}

    //! Normalize a vector.
    void Normalize() {float l = 1.0/Lenght(); x = x*l; y = y*l; z = z*l;}

    //! Get -v;
    /*!
          \return return a Vector3 -v.
    */
    Vector3 operator- () const { return Vector3( -x, -y, -z ); }

    //! Get v1+v2.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return a Vector3 v1+v2.
    */
    friend Vector3 operator + ( const Vector3& v1, const Vector3& v2 ) { return Vector3( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); }

    //! Get v1-v2.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return a Vector3 v1-v2.
    */
    friend Vector3 operator - ( const Vector3& v1, const Vector3& v2 ) { return Vector3( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); }

    //! Get v1*v2.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return a Vector3 v1*v2.
    */
    friend Vector3 operator * ( const Vector3& v1, const Vector3& v2 ) { return Vector3( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z ); }

    //! Get v1*t.
    /*!
          \param v1 a Vector3.
          \param t a float value.
          \return return a Vector3 v1*t.
    */
    friend Vector3 operator * ( const Vector3& v1, const float t ) { return Vector3(v1.x*t, v1.y*t, v1.z*t ); }

    //! Get t*v1.
    /*!
          \param t a float value.
          \param v1 a Vector3.
          \return return a Vector3 t*v1.
    */
    friend Vector3 operator * ( const float t, const Vector3& v1 ) { return Vector3(v1.x*t, v1.y*t, v1.z*t ); }

    //! Get v1/t.
    /*!
          \param v1 a Vector3.
          \param t a float value.
          \return return a Vector3 v1/t.
    */
    friend Vector3 operator / ( const Vector3& v1, const float t ) { return Vector3(v1.x/t, v1.y/t, v1.z/t ); }

    //! Reture v1==v2.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return true if v1==v2, or return false.
    */
    friend bool operator == ( const Vector3& v1, const Vector3& v2 ) { return (v1.x==v2.x&&v1.y==v2.y&&v1.z*v2.z); }

    //! Get cross product.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return a Vector3 of the cross product of v1 and v2.
    */
    friend Vector3 Cross(const Vector3& v1, const Vector3& v2) { return Vector3( v1.y*v2.z-v2.y*v1.z, v1.z*v2.x-v2.z*v1.x, v1.x*v2.y-v2.x*v1.y ); }

    //! Get dot product.
    /*!
          \param v1 a Vector3.
          \param v2 a Vector3.
          \return return a float value of the dot product of v1 and v2.
    */
    friend float Dot(const Vector3& v1, const Vector3& v2) { return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; }

    //! x coordinate value.
    double x;

    //! y coordinate value.
    double y;

    //! z coordinate value.
    double z;
};

#endif // COMMON_H
